package com.uminho.http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.AbstractHttpParams;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;



/****c* Connection/HTTP
 * DESCRIPTION
 * Classe responsável por oferecer suporte aos pedidos Http
 *
 ****
 */
public class Http {

	// Default timeout
	//private static final int SOCKET_TIMEOUT = 15000;
	private static final int CONNECTION_TIMEOUT = 15000;


	/****f* HTTP/executeHttpPost
	 * DESCRIPTION
	 * Método criado para executar pedidos POST
	 * INPUTS
	 * O URL do pedido e uma lista de headers
	 * RESULT
	 * String com o resultado do pedido
	 ****
	 */
	public static String executeHttpPost(String URL,
			ArrayList<BasicNameValuePair> header)
			throws ClientProtocolException, IOException {
		BufferedReader in = null;
		try {
			
			HttpClient client = newClient();
		    
			HttpPost request = new HttpPost(URL);
			List<NameValuePair> postParameters = new ArrayList<NameValuePair>();
			request.addHeader("Accept", "application/json");
			// postParameters.add(new BasicNameValuePair("filename", "xyz"));

			for (BasicNameValuePair h : header) {
				postParameters.add(h);
			}
			
			UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(
					postParameters);
			request.setEntity(formEntity);
			HttpResponse response = client.execute(request);
			in = new BufferedReader(new InputStreamReader(response.getEntity()
					.getContent()));
			StringBuffer sb = new StringBuffer("");
			String line = "";
			String NL = System.getProperty("line.separator");
			while ((line = in.readLine()) != null) {
				sb.append(line + NL);
			}
			in.close();
			String result = sb.toString();
			return result;
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/****f* HTTP/executeHttpPost
	 * DESCRIPTION
	 * Método criado para executar pedidos POST
	 * INPUTS
	 * O URL do pedido e uma lista de headers e um token
	 * RESULT
	 * String com o resultado do pedido
	 ****
	 */
	public static String executeHttpPost(String URL,
			ArrayList<BasicNameValuePair> header, String token)
			throws ClientProtocolException, IOException {
		BufferedReader in = null;
		try {
			HttpClient client = newClient();
			HttpPost request = new HttpPost(URL);
			List<NameValuePair> postParameters = new ArrayList<NameValuePair>();
			for (BasicNameValuePair h : header) {
				postParameters.add(h);
			}
			request.addHeader("Accept", "application/json");
			request.addHeader("Authorization", "OAuth "+ token);
			UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(
					postParameters);
			request.setEntity(formEntity);
			HttpResponse response = client.execute(request);
			in = new BufferedReader(new InputStreamReader(response.getEntity()
					.getContent()));
			StringBuffer sb = new StringBuffer("");
			String line = "";
			String NL = System.getProperty("line.separator");
			while ((line = in.readLine()) != null) {
				sb.append(line + NL);
			}
			in.close();
			String result = sb.toString();
			return result;
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	
	/****f* HTTP/executeHttpPut
	 * DESCRIPTION
	 * Método criado para executar pedidos POST
	 * INPUTS
	 * O URL do pedido e uma lista de headers e um token
	 * RESULT
	 * String com o resultado do pedido
	 ****
	 */
	public static String executeHttpPut(String URL,
			ArrayList<BasicNameValuePair> header, String token)
			throws ClientProtocolException, IOException {
		BufferedReader in = null;
		try {
			HttpClient client = newClient();
			HttpPut request = new HttpPut(URL);
			List<NameValuePair> postParameters = new ArrayList<NameValuePair>();
			for (BasicNameValuePair h : header) {
				postParameters.add(h);
			}
			request.addHeader("Accept", "application/json");
			request.addHeader("Authorization", "OAuth "+ token);
			UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(
					postParameters);
			request.setEntity(formEntity);
			HttpResponse response = client.execute(request);
			in = new BufferedReader(new InputStreamReader(response.getEntity()
					.getContent()));
			StringBuffer sb = new StringBuffer("");
			String line = "";
			String NL = System.getProperty("line.separator");
			while ((line = in.readLine()) != null) {
				sb.append(line + NL);
			}
			in.close();
			String result = sb.toString();
			return result;
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	/****f* HTTP/executeHttpDelete
	 * DESCRIPTION
	 * Método criado para executar pedidos Delete
	 * INPUTS
	 * O URL do pedido e um token
	 * RESULT
	 * String com o resultado do pedido
	 ****
	 */
	public static String executeHttpDelete(String URL, String token)
			throws ClientProtocolException, IOException {
		BufferedReader in = null;
		try {
			HttpClient client = newClient();
			HttpDelete request = new HttpDelete(URL);

			request.addHeader("Accept", "application/json");
			request.addHeader("Authorization", "OAuth "+ token);
			HttpResponse response = client.execute(request);
			
			in = new BufferedReader(new InputStreamReader(response.getEntity()
					.getContent()));
			StringBuffer sb = new StringBuffer("");
			String line = "";
			String NL = System.getProperty("line.separator");
			while ((line = in.readLine()) != null) {
				sb.append(line + NL);
			}
			in.close();
			String result = sb.toString();
			return result;
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/****f* HTTP/executeHttpGet
	 * DESCRIPTION
	 * Método criado para executar pedidos Get
	 * INPUTS
	 * O URL do pedido 
	 * RESULT
	 * String com o resultado do pedido
	 ****
	 */
	public static String executeHttpGet(String URL) throws URISyntaxException,
			ClientProtocolException, IOException {
		BufferedReader in = null;
		try {
			HttpClient client = newClient();
			HttpGet request = new HttpGet();
			request.setURI(new URI(URL));
			request.addHeader("Accept", "application/json");

			HttpResponse response = client.execute(request);
			in = new BufferedReader(new InputStreamReader(response.getEntity()
					.getContent()));
			StringBuffer sb = new StringBuffer("");
			String line = "";
			String NL = System.getProperty("line.separator");
			while ((line = in.readLine()) != null) {
				sb.append(line + NL);
			}
			in.close();
			String page = sb.toString();
			return page;
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	
	/****f* HTTP/executeHttpGet
	 * DESCRIPTION
	 * Método criado para executar pedidos Get
	 * INPUTS
	 * O URL do pedido, Lista com os header do pedido  
	 * RESULT
	 ****
	 * String com o resultado do pedido
	 */
	public static String executeHttpGet(String URL,
			ArrayList<BasicNameValuePair> header) throws URISyntaxException,
			ClientProtocolException, IOException {
		BufferedReader in = null;
		try {
			HttpClient client = newClient();
			HttpGet request = new HttpGet();
			request.setURI(new URI(URL));
			request.addHeader("Accept", "application/json");

			for (BasicNameValuePair h : header) {
				request.addHeader(h.getName(), h.getValue());
			}
			
			HttpResponse response = client.execute(request);
			in = new BufferedReader(new InputStreamReader(response.getEntity()
					.getContent()));
			StringBuffer sb = new StringBuffer("");
			String line = "";
			String NL = System.getProperty("line.separator");
			while ((line = in.readLine()) != null) {
				sb.append(line + NL);
			}
			in.close();
			String page = sb.toString();
			return page;
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	private static HttpClient newClient(){
		HttpClient client = new DefaultHttpClient();
		AbstractHttpParams httpParameters = new BasicHttpParams();
		HttpConnectionParams.setConnectionTimeout(httpParameters, CONNECTION_TIMEOUT);
//	    HttpConnectionParams.setSoTimeout(httpParameters, SOCKET_TIMEOUT);
	    client = new DefaultHttpClient(httpParameters);
	    return client;
	}
}
